package com.gopay.scheduler.job;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.common.datasource.DBType;
import com.gopay.common.datasource.DbContextHolder;
import com.gopay.common.domain.report.ReportConsoleBalanceQuery;
import com.gopay.common.order.dao.CommonQueryDAO;
import com.gopay.common.report.dao.MqEventInfoDAO;
import com.gopay.common.report.dao.ReportConsoleBalanceQueryDAO;
import com.gopay.common.util.DateUtils;
import com.gopay.scheduler.GopayBaseJob;
import com.gopay.scheduler.service.reporthandler.AcctBalanceService;

/**
 * 报表账户余额每日统计Job
 * 
 * @ReportAcctBalanceDailyStatiJob.java
 * @author fanghw
 * @2015年6月23日 下午3:31:50 www.gopay.com.cn Inc.All rights reserved.
 */
public class ReportAcctBalanceDailyStatiJob extends GopayBaseJob {
    // 日志
    private Logger logger = LoggerFactory.getLogger(ReportAcctBalanceDailyStatiJob.class);

    @Resource(name = "reportConsoleBalanceQueryDAO")
    private ReportConsoleBalanceQueryDAO reportConsoleBalanceQueryDAO;
    
    @Resource(name="mqEventInfoDAO")
    private MqEventInfoDAO mqEventInfoDAO;
    
    @Resource(name="acctBalanceService")
    private AcctBalanceService acctBalanceService;

    @Override
    public void doJobInternal() {
        
        
        // 当前时间
        Date curDate = new Date();

        // 今天
        String today = DateUtils.format(curDate, "yyyyMMdd");

        // 计算昨天
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(curDate);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        // 昨天
        String yesterday = DateUtils.format(calendar.getTime(), "yyyyMMdd");
        //记账日期为昨天
        Date acctDate=calendar.getTime();

        List<ReportConsoleBalanceQuery> acctBalList = null;
        int pageNum = 1;
        int pageSize=1000;
        do {
            // 查询
            acctBalList = acctBalanceService.queryAcctBalance(yesterday, today,pageNum,pageSize);
            logger.error("-------acctBalList.size="+acctBalList.size());
            DbContextHolder.setDbType(DBType.DS_REPORT.value);
            for(ReportConsoleBalanceQuery ab :acctBalList){
                ab.setAcctTs(acctDate);
                ab.setCreatedTs(curDate);
                ab.setLastUpdTs(curDate);
                                
                //保存
                saveAcctBalance(ab,today);
            }

            pageNum++;
        } while (acctBalList.size() > 0);
        
        
        logger.error("去除已结束的重复事件---开始");
        //去除已结束的重复事件
        DbContextHolder.setDbType(DBType.DS_REPORT.value);
        int removeCount=removeFinishedSameEvent(yesterday);
        logger.error("去除已结束的重复事件---结束,去重记录数="+removeCount);

        
    }

   
    
    
    private void saveAcctBalance(ReportConsoleBalanceQuery ab,String acctTs){
        String hql="FROM ReportConsoleBalanceQuery WHERE acctTs=TO_DATE(:acctTs, 'YYYYMMDD') and acctId=:acctId";
        Map<String, Object> map=new HashMap<String, Object>();
        map.put("acctTs", acctTs);
        map.put("acctId", ab.getAcctId());
        
        List<ReportConsoleBalanceQuery> rsList=reportConsoleBalanceQueryDAO.findByHql(hql, map);
        if(rsList==null||rsList.size()==0){
            reportConsoleBalanceQueryDAO.save(ab);
        }
    }
    
    /**
     * 去除已结束的重复事件
     * @param beginDate
     */
    private int removeFinishedSameEvent(String beginDate){
        StringBuilder sb = new StringBuilder();

        sb.append(" delete from mq_event_info t2 ");
        sb.append(" where exists (select 1 ");
        sb.append("          from (select r.* ");
        sb.append("                  from (select t.dtl_sq, ");
        sb.append("                               t.gopay_order_id, ");
        sb.append("                               t.type, ");
        sb.append("                               t.stat, ");
        sb.append("                               dense_rank() over(partition by t.gopay_order_id, t.type, t.stat order by t.dtl_sq asc) rank ");
        sb.append("                          from mq_event_info t ");
        sb.append("                         where 1 = 1 ");
        sb.append("                          and t.stat in ('02', '03') ");
        sb.append("                           and t.created_ts >= ");
        sb.append("                               to_timestamp(:beginDate, 'yyyymmdd')) r ");
        sb.append("                 where r.rank > 1 ");
        sb.append("                 order by r.gopay_order_id, r.type, r.stat) t1 ");
        sb.append("         where t1.dtl_sq = t2.dtl_sq) ");
        
        
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("beginDate", beginDate);
        
        return mqEventInfoDAO.updateBySql(sb.toString(), map);

    }

}
